﻿using System;
using System.IO;
using Codemo.Core.Applications;
using ICSharpCode.SharpZipLib.Zip;

namespace Codemo.Core.Deployment.Tasks
{
    /// <summary>
    /// 
    /// </summary>
    public class ExtractToTempDirectoryTask : DeploymentTask
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="ExtractToTempDirectoryTask"/> class.
        /// </summary>
        /// <param name="application">The application.</param>
        /// <param name="deploymentConfigurationVersion">The deployment configuration version.</param>
        /// <param name="deploymentTarget">The deployment target.</param>
        /// <param name="package">The package.</param>
        public ExtractToTempDirectoryTask(Application application,
                                          DeploymentConfigurationVersion deploymentConfigurationVersion,
                                          DeploymentTarget deploymentTarget, Package package)
            : base(application, deploymentConfigurationVersion, deploymentTarget, package)
        {
        }

        /// <summary>
        /// Copy the package to the temporary directory
        /// </summary>
        public override void Execute()
        {
            if (Package.Exists)
            {
                DirectoryInfo temporaryDirectory = Application.TemporaryDirectory;

                // delete the directory if exists
                if (temporaryDirectory.Exists)
                {
                    temporaryDirectory.Delete(true);
                }

                UnZip(Package.FullName, temporaryDirectory.FullName);

                //TODO add log & try/catch
            }
        }

        private static void UnZip(string zipPath, string extractDir)
        {
            using (var s = new ZipInputStream(File.OpenRead(zipPath)))
            {
                ZipEntry theEntry;

                while ((theEntry = s.GetNextEntry()) != null)
                {
                    string directoryName = Path.GetDirectoryName(theEntry.Name);
                    string fileName = Path.GetFileName(theEntry.Name);

                    // create directory
                    if (directoryName.Length > 0)
                    {
                        Directory.CreateDirectory(Path.Combine(extractDir, directoryName));
                    }

                    if (fileName != String.Empty)
                    {
                        using (FileStream streamWriter = File.Create(Path.Combine(extractDir, theEntry.Name)))
                        {
                            int size = 2048;
                            var data = new byte[size];
                            while (true)
                            {
                                size = s.Read(data, 0, data.Length);
                                if (size > 0)
                                {
                                    streamWriter.Write(data, 0, size);
                                }
                                else
                                {
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}